package in.iqing.control.util;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.Deflater;

/**
 * Created by neavo on 2015/5/15.
 */

public class ZipUtil {

	private synchronized static void getFiles(File source, List<File> files) {
		if (source.isFile()) {
			files.add(source);
		} else {
			File[] children = source.listFiles();
			for (File file : children != null ? children : new File[0]) {
				getFiles(file, files);
			}
		}
	}

	public synchronized static void compress(File source, File target) throws IOException {
		List<File> files = new ArrayList<>();
		Integer length = source.getPath().length() + 1;
		ZipArchiveOutputStream zipos = new ZipArchiveOutputStream(target);

		getFiles(source, files);
		zipos.setLevel(Deflater.BEST_SPEED);

		for (File file : files) {
			InputStream is = FileUtils.openInputStream(file);
			byte[] binary = IOUtils.toByteArray(is);
			IOUtils.closeQuietly(is);

			ZipArchiveEntry entry = new ZipArchiveEntry(file.getPath().substring(length));
			entry.setSize(binary.length);

			zipos.putArchiveEntry(entry);
			zipos.write(binary);
			zipos.closeArchiveEntry();
		}

		IOUtils.closeQuietly(zipos);
	}

	public synchronized static String decompressString(File source, String target) throws IOException {
		String result;
		ZipFile zipFile = new ZipFile(source);
		InputStream is = zipFile.getInputStream(zipFile.getEntry(target));

		result = IOUtils.toString(is);

		IOUtils.closeQuietly(is);
		IOUtils.closeQuietly(zipFile);
		return result;
	}

	public synchronized static void decompress(File source, File result, String target) throws IOException {
		ZipFile zipFile = new ZipFile(source);
		OutputStream os = FileUtils.openOutputStream(result);
		InputStream is = zipFile.getInputStream(zipFile.getEntry(target));

		IOUtils.copy(is, os);

		IOUtils.closeQuietly(os);
		IOUtils.closeQuietly(is);
		IOUtils.closeQuietly(zipFile);
	}
}
